<template>
  <div class="number-input">
    <el-input
      v-model="input"
      :maxlength="maxLength"
      :size="size"
      :disabled="disabled"
      :clearable="clearable"
      :placeholder="placeholder"
      @paste.native.capture="handlerFalse($event)"
      @copy.native.capture="handlerFalse($event)"
      @cut.native.capture="handlerFalse($event)"
      @focus="handlerFocus"
      @input="handlerInput"
      @blur="handlerBlur"
    >
      <template slot="append" v-if="unit">
        <el-button>{{ unit }}</el-button>
      </template>
    </el-input>
  </div>
</template>

<script>
export default {
  name: 'NumberInputOld',
  props: {
    // 是否展示成千分位
    showThousands: {
      type: Boolean,
      default: false
    },
    // 是否可以输入负数
    showNegative: {
      type: Boolean,
      default: false
    },
    // 是否可以输入小数
    showDecimal: {
      type: Boolean,
      default: false
    },
    placeholder: {
      type: String,
      deault: '请输入 数字'
    },
    // 整数位数
    integerCount: {
      type: Number,
      default: 12
    },
    // 小数位数
    decimalCount: {
      type: Number,
      default: 2
    },
    size: {
      type: String,
      default: 'small'
    },
    disabled: {
      type: Boolean,
      default: false
    },
    // 默认值
    initNum: {
      type: [Number, String],
      default: null
    },
    max: {
      type: Number,
      default: null
    },
    min: {
      type: Number,
      default: null
    },
    unit: {
      type: String,
      default: null
    },
    // 是否需要补零
    needAddZero: {
      type: Boolean,
      default: false
    },
    clearable: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      input: '', // 输入框的值(字符串格式，千分化的)
      realValue: '' // 实际数字(字符串格式，没有千分化的)
    };
  },
  computed: {
    // 输入框最大限制长度(默认整数最大12位，小数2位，负号1位，小数点1位)
    maxLength() {
      let {
        showNegative,
        showDecimal,
        integerCount,
        decimalCount
      } = this;
      return integerCount + (showDecimal ? decimalCount : 0) + (showNegative ? 1 : 0) + (showDecimal ? 1 : 0);
    }
  },
  watch: {
    initNum: {
      handler(newVal) {
        this.input = newVal;
        this.handlerBlur();
      }
    }
  },
  mounted() {
    this.input = this.initNum;
    this.handlerBlur();
  },
  methods: {
    handlerFocus() {
      if (String(this.input).indexOf(',') > -1) {
        this.input = this.input.replace(/,/g, '');
      }
    },
    handlerInput(value) {
      let {
        showNegative,
        showDecimal,
        integerCount,
        decimalCount
      } = this;
      integerCount = integerCount < 1 ? 1 : Math.floor(integerCount); // 整数部分最少1位
      decimalCount = decimalCount < 1 ? 1 : Math.floor(decimalCount); // 小数部分最少1位
      let handleValue = value;
      // 去除非法字符
      let reg1 = showNegative ? showDecimal ? /[^-\d.]/g : /[^-\d]/g : showDecimal ? /[^\d.]/g : /[^\d]/g;
      handleValue = handleValue.replace(reg1, '');
      // 开头是0或者-0，如果其后紧接着又是0，则只保留一个0
      let reg2 = /^(-?)(0)+/g;
      handleValue = handleValue.replace(reg2, '$1$2');
      // 开头是0或者-0，如果其后是[1-9]的数字，就用这个数字替换掉前面的0
      let reg3 = /^(-?)(0)([1-9])/g;
      handleValue = handleValue.replace(reg3, '$1$3');
      // 开头是.或者-.，去掉这个.
      let reg4 = /^(-?)[.]/g;
      handleValue = handleValue.replace(reg4, '$1');
      let reg5 = new RegExp(`^${showNegative ? '-?' : null}((0(\\.\\d{1,${decimalCount}})?)|([1-9](\\d{0,${integerCount - 1}})?(\\.\\d{1,${decimalCount}})?))$`);
      if (!reg5.test(handleValue)) {
        let ary = handleValue.split('');
        // 去除多余的小数点
        if (showDecimal) {
          let dotLen = 0;
          let dotIdx = -1;
          ary.forEach((ls, index) => {
            if (ls === '.') {
              dotLen++;
              dotIdx = index;
            }
          });
          if (dotLen === 1) { // 如果小数点只有一个
            if (dotIdx === 0) { // 小数点在第一个的位置
              ary.splice(dotIdx, 1);
              handleValue = ary.join('');
            } else {
              // 小数点前面不是数字
              if (/[^\d]/.test(ary.slice(dotIdx - 1, dotIdx)[0])) {
                ary.splice(dotIdx, 1);
                handleValue = ary.join('');
              }
            }
          } else if (dotLen === 2) {
            ary.splice(dotIdx, 1);
            handleValue = ary.join('');
          }
        }
        // 去掉多余的负号
        if (showNegative) {
          let negLen = 0;
          let negIdx = -1;
          ary.forEach((ls, index) => {
            if (ls === '-') {
              negLen++;
              negIdx = index;
            }
          });
          if (negLen === 1) { // 负号只有一个
            if (negIdx !== 0) { // 负号不在第一个的位置
              ary.splice(negIdx, 1);
              handleValue = ary.join('');
            }
          } else if (negLen === 2) {
            ary.splice(negIdx, 1);
            handleValue = ary.join('');
          }
        }
        // 处理数字
        if (handleValue.indexOf('.') > -1) { // 有小数点
          let arr = handleValue.split('.');
          let len = arr[0].indexOf('-') > -1 ? integerCount + 1 : integerCount;
          let pre = arr[0].length > len ? arr[0].slice(0, len) : arr[0];
          let suf = '';
          if (arr[1]) {
            suf = arr[1].length > decimalCount ? arr[1].slice(0, decimalCount) : arr[1];
          }
          handleValue = [pre, '.', suf].join('');
        } else { // 没有小数点
          let len = handleValue.indexOf('-') > -1 ? integerCount + 1 : integerCount;
          handleValue = handleValue.length > len ? handleValue.slice(0, len) : handleValue;
        }
      }
      // 处理结束
      this.input = handleValue;
    },
    handlerBlur() {
      let {
        showThousands,
        showDecimal,
        decimalCount,
        max,
        min,
        needAddZero
      } = this;
      decimalCount = decimalCount < 1 ? 1 : Math.floor(decimalCount); // 小数部分最少1位
      // 只输入了一个负号
      if (this.input === '-') {
        this.input = null;
      }
      // 处理大于最大值或者小于最小值的情况
      if (this.input === 0 || this.input === '0' || this.input) {
        if (max === 0 || max) {
          if (Number(this.input) > max) {
            this.input = String(max);
          }
        }
        if (min === 0 || min) {
          if (Number(this.input) < min) {
            this.input = String(min);
          }
        }
      }
      // 补零
      if (showDecimal) {
        if (this.input === 0 || this.input === '0' || this.input) {
          if (this.input == 0) {
            if (needAddZero) {
              this.input = '0.' + new Array(decimalCount).fill(0).join('');
            }
          } else if (this.input) {
            let arr = this.input.toString().split('.');
            let ary = [arr[0], '.'];
            if (needAddZero) {
              if (arr[1]) {
                if (arr[1].length < decimalCount) {
                  ary.push(arr[1], new Array(decimalCount - arr[1].length).fill(0).join(''));
                } else {
                  ary.push(arr[1]);
                }
              } else {
                ary.push(new Array(decimalCount).fill(0).join(''));
              }
            } else {
              if (arr[1]) {
                ary.push(arr[1]);
              } else {
                ary = ary.slice(0, 1);
              }
            }
            this.input = ary.join('');
          }
        }
      }
      this.realValue = this.input;
      if (showThousands) {
        // 千分化
        this.input = (this.input === 0 || this.input === '0' || this.input) && this.input.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
      }
      this.setValue();
    },
    setValue() {
      this.$emit('change', this.realValue);
    },
    handlerFalse(e) {
      e.preventDefault();
    }
  }
};
</script>

<style lang="scss" scoped></style>